<?php
namespace control;
/*
*收款单类
*/

class inReceiptClass extends adIndexClass
{
    private const page = 'inReceipt';
    private const table = 'receipt';
    private const tableMx = 'receipt_detail';
    private const title = '收款单';

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            case 'clientInSearch':
                $tr = [
                    'orderNo'          => [
                        'name'  => L('inReceipt.homeSearch.orderNo'),
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'money'         => [
                        'name'  => L('inReceipt.homeSearch.money')."(" . static::$unit . ")",
                        'width' => 200,
                    ],
                    'checkMoney'          => [
                        'name'  => L('inReceipt.homeSearch.checkMoney')."(" . static::$unit . ")",
                        'width' => 200,
                    ],
                    'collectInAdvance'          => [
                        'name'  => L('inReceipt.homeSearch.collectInAdvance')."(" . static::$unit . ")",
                        'width' => 200,
                    ],
                    'manager'          => [
                        'name'  => L('inReceipt.homeSearch.manager'),
                        'width' => 200,
                    ],
                    'recordDate'          => [
                        'name'  => L('inReceipt.homeSearch.recordDate'),
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'state'          => [
                        'name'  => L('inReceipt.homeSearch.state'),
                        'width' => 150,
                    ]
                ];
                break;
            default:
                $tr = [
                    'orderNo'          => [
                        'name'  => L('inReceipt.homeSearch.orderNo'),
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'targetName'  => [
                        'name'  => L('inReceipt.homeSearch.targetName'),
                        'width' => 200,
                    ],
                    'money'         => [
                        'name'  => L('inReceipt.homeSearch.money')."(" . static::$unit . ")",
                        'width' => 200,
                    ],
                    'checkMoney'          => [
                        'name'  => L('inReceipt.homeSearch.checkMoney')."(" . static::$unit . ")",
                        'width' => 200,
                    ],
                    'collectInAdvance'          => [
                        'name'  => L('inReceipt.homeSearch.collectInAdvance')."(" . static::$unit . ")",
                        'width' => 200,
                    ],
                    'manager'          => [
                        'name'  => L('inReceipt.homeSearch.manager'),
                        'width' => 200,
                    ],
                    'recordDate'          => [
                        'name'  => L('inReceipt.homeSearch.recordDate'),
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'state'          => [
                        'name'  => L('inReceipt.homeSearch.state'),
                        'width' => 150,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function clientInOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    L('inReceipt.clientIn.orderNo') => text(array("name" => "orderNo")).
                        hidden(array("name" => "targetId", "value" => $this->get('id'))),
                    L('inReceipt.clientIn.createTime')   => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                    L('inReceipt.clientIn.state') => select(["name" => "state", 'option' => ['草稿', '待确认', '已确认']]),
                ],
                [
                    L('inReceipt.clientIn.staff') => selectMultiple(["name" => "stid", 'table' => " staff", 'sqlId' => 'stid', 'sqlField' => 'name']),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 客户页卡
     * @return bool|string
     */
    public function clientIn(): bool|string
    {
        $html = $this->clientInOptions(false);
        $button = "";
        //返回
        $json['html'] = $this->search($html, layout: 'pop', toolButton: $button);
        return json_encode($json, 320);
    }

    public function clientInSearch(): bool|string
    {
        $khid = $this->post('targetId');
        //like查询数组
        $like = array(
            "orderNo" => $this->post('orderNo'),
        );
        //全等查询数组
        $equal = array(
            "manager" => $this->post('stid'),
            "state" => $this->post('state'),
            'coid' => self::$coid,
            'classify' => 1
        );
        $and = " and targetId = '$khid'";
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), 'date', 'recordDate');
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        //生成查询语句
        $where = search([
                "=" => $equal,
                "like" => $like,
            ]) . $and;
        $page = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array("");
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "detail" => ["title" => L('inReceipt.clientInSearch.detail'), "click" => "newIframe('" . L('inReceipt.clientInSearch.detail') . "','" . root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=detail&id=' . $array['id'] . "')"],
            );
            //收款金额
            $money = find(array('table' => self::table . "_detail", 'where' => "orderId = '$array[id]'", 'sum' => "money"));
            //核销金额
            $checkMoney = find(array('table' => self::table . "_source", 'where' => "orderId = '$array[id]'", 'sum' => "money"));
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'money':
                        $row[] = $money;
                        break;
                    case 'checkMoney':
                        $row[] = $checkMoney;
                        break;
                    case 'collectInAdvance':
                        $row[] = $money - $checkMoney;
                        break;
                    case 'manager':
                        $row[] = self::findStaff($array['manager']);
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        $totalQuery = find([
            'table'  => self::table . "_detail",
            'single' => " orderId in (select id from ".self::table." where 1=1 {$where}) ",
            'field'  => "ifnull(sum(money),0) as money",
        ]);
        $checkQuery = find([
            'table'  => self::table . "_source",
            'single' => " orderId in (select id from ".self::table." where 1=1 {$where}) ",
            'field'  => "ifnull(sum(money),0) as money",
        ]);
        $total    = [
            'money'        => $totalQuery['money'],
            'checkMoney'        => $checkQuery['money'],
            'collectInAdvance'        => round($totalQuery['money'] - $checkQuery['money'],2),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] = $page['hint'] . "<form name='inForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    L('inReceipt.home.orderNo') => text(array("name" => "orderNo")),
                    L('inReceipt.home.targetName')   => text(array("name" => "targetName")),
                    L('inReceipt.home.createTime') => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                ],
                [
                    L('inReceipt.home.state') => select(["name" => "state", 'option' => ['草稿', '待确认', '已确认']]),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"newIframe('" . L('inReceipt.homeSearch.detail') . "','" . $url . "&fun=edit')\" class='spanButton'>".L('inReceipt.homeSearch.new')."</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">".L('inReceipt.homeSearch.del')."</span>\n";
        }
        if ($this->power(self::page, "print")) {
            $button .= " <span onclick=\"batchPrint('" . $this->get('cla') . "')\" class='spanButton'>批量打印</span>\n";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {

        //like查询数组
        $like = array(
            "orderNo" => $this->post('orderNo'),
        );
        //全等查询数组
        $equal = array(
            "state" => $this->post('state'),
            "targetName" => $this->post('targetName'),
            'coid' => self::$coid,
            'classify' => 1
        );
        $and = '';
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), 'date', 'recordDate');
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        $print = $this->power(self::page,'print');
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box" => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => L('inReceipt.homeSearch.edit'), "click" => "newIframe('" . L('inReceipt.homeSearch.detail') . "','" . $url . "&fun=edit&id=" . $array['id'] . "')"),
                "detail" => array("title" => L('inReceipt.homeSearch.detail'), "click" => "newIframe('" . L('inReceipt.homeSearch.detail') . "','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
                'print' => $print?array('title' => '打印', 'click' => "window.open('" . root . "control/adIndex.html?cla=" . self::page . "&fun=printPage&id={$array['id']}')"):[],
            );
            if ($array['state'] == '已确认') {
                unset($dominate['edit']);
            }
            //收款金额
            $money = find(array('table' => self::table . "_detail", 'where' => "orderId = '$array[id]'", 'sum' => "money"));
            //核销金额
            $checkMoney = find(array('table' => self::table . "_source", 'where' => "orderId = '$array[id]'", 'sum' => "money"));
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'money':
                        $row[] = $money;
                        break;
                    case 'checkMoney':
                        $row[] = $checkMoney;
                        break;
                    case 'collectInAdvance':
                        $row[] = $money - $checkMoney;
                        break;
                    case 'manager':
                        $row[] = self::findStaff($array['manager']);
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        $totalQuery = find([
            'table'  => self::table . "_detail",
            'single' => " orderId in (select id from ".self::table." where 1=1 {$where}) ",
            'field'  => "ifnull(sum(money),0) as money",
        ]);
        $checkQuery = find([
            'table'  => self::table . "_source",
            'single' => " orderId in (select id from ".self::table." where 1=1 {$where}) ",
            'field'  => "ifnull(sum(money),0) as money",
        ]);
        $total    = [
            'money'        => $totalQuery['money'],
            'checkMoney'        => $checkQuery['money'],
            'collectInAdvance'        => round($totalQuery['money'] - $checkQuery['money'],2),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total"       => $total,
        ));
        //返回
        $json['html'] = $page['hint'] . "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }


    /**
     * 销售或采购单据金额
     */
    private static function sale_money($sourceTable, $sourceId)
    {
        $totalMoney = 0;
        if ($sourceTable == 'sale_send_order') {
            //单据金额
            $totalMoney = find(array('table' => 'sale_send_order_detail as a join inventory_detail as b on a.id = b.sourceId', "single" => "a.orderId = '$sourceId'", 'field' => "ifnull(sum(a.money),0) as total"))['total'] ?? 0;
        } elseif ($sourceTable == 'sale_refund_order') {
            //单据金额
            $totalMoney = find(array('table' => 'sale_refund_order_detail as a join inventory_detail as b on a.id = b.sourceId', "single" => "a.orderId = '$sourceId'", 'field' => "ifnull(sum(a.money),0) as total"))['total'] ?? 0;
        }
        return $totalMoney;
    }

    /**
     * 获取结算日期
     * @param $type
     * @param $date
     * @param $day
     * @return string
     */
    public function settlementPeriod($type,$date,$day){
        return match ($type){
            '月结'=>date('Y-m-d',strtotime("+{$day} day",strtotime($date))),
            default=>$date,
        };
    }

    /**
     * 保存并提交
     * @return bool|string
     */
    public function saveAndCommit(): bool|string
    {
        $resultJson = $this->editEdit();
        $result = json_decode($resultJson,true);
        if ($result['warn'] == 2){
            unset($_SESSION['warn']);
            $resultJson = $this->commitEdit();
        }
        return $resultJson;
    }
    /**
     * 编辑页
     * @return string
     */
    public function edit(): string
    {
        $id = $this->get('id') ?: self::getId();
        $info = query(self::table, " id = '" . $id . "' ");

        $button[] = [
            "name" => '保存',
            "type" => "点击事件",
            "title" => '保存为草稿',
            'fun' => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit')"
        ];
//        $button[] = [
//            'style' => 'li-btn-blue-bg',
//            "name" => "保存并提交",
//            "type" => "点击事件",
//            "title" => "保存",
//            'fun' => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=saveAndCommit')"
//        ];
        $tr[] = ['', L('inReceipt.edit.account'), L('inReceipt.edit.money').'(' . static::$unit . ')', L('inReceipt.edit.settleType'), L('inReceipt.edit.settleNo'), L('inReceipt.edit.mxText')];
        $result = find(array(
            'field' => "id as mxId,acid,money as income,settleType,settleNo,text as mxText",
            'table' => self::table . "_detail"." where orderId = '$info[id]' order by list"
        ));
        if(count($result['array']) > 0) {
            foreach ($result['array'] as $k=>$array) {
                $array['list'] = $k+1;
                $tr[] = $this->listRow($array);
            }
        }else{
            $tr[] = $this->listRow(['mxId'=>self::getId(), 'list'=>1]);
        }

        $checkMoneyTotal = 0;
        $sourceTr[] = ['', L('inReceipt.edit.sOrderNo'), L('inReceipt.edit.type'), L('inReceipt.edit.recordDate'), L('inReceipt.edit.settlementType'),L('inReceipt.edit.period'),L('inReceipt.edit.totalMoney').'(' . static::$unit . ')', L('inReceipt.edit.checkMoney').'(' . static::$unit . ')', L('inReceipt.edit.notWrittenOff').'(' . static::$unit . ')', L('inReceipt.edit.thisMoney').'(' . static::$unit . ')'];
        $result = find(array('table' => self::table . "_source", 'where' => "orderId = '$info[id]' order by list"));
        foreach ($result['array'] as $k=>$array) {
            $settlementType = '';
            $period = '';
            if ($array['sourceTable'] == 'sale_send_order') {
                $type = '销售发货单';
                $mx = query('sale_send_order', "id = '$array[sourceId]'");
                $settlementType = $mx['settlementType'];
                $period = $this->settlementPeriod($mx['settlementType'],$mx['recordDate'],$mx['settlementDay']);
            } else {
                $type = '销售退货单';
                $mx = query('sale_refund_order', "id = '$array[sourceId]'");
            }
            //单据金额
            $totalMoney = self::sale_money($array['sourceTable'], $array['sourceId']);
            if ($mx['khid'] != $info['targetId']) {
                //转过的单子
                $totalMoney = find(array('table' => 'write_off_order_replace', "where" => "sourceId = '$mx[id]' and targetIn = '$info[targetId]'", 'sum' => "money"));
            }
            $totalMoney = $type == '销售退货单' ? -round($totalMoney, 2) : round($totalMoney, 2);
            $checkMoney = find(array('table' => "receipt_source as a join receipt as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$mx[id]'", 'sum' => "money"));
            $checkMoney += find(array('table' => "write_off_order_detail as a join write_off_order as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$mx[id]'", 'sum' => "money"));
            $checkMoneyTotal+=$array['money'];
            $sourceTr[] = [
                componentClass::tablePperation($k+1,"delTableRow(this)").
                hidden(array('name' => 'detailId[]', 'value' => $array['id'])) .
                hidden(array('name' => 'sourceId[]', 'value' => $array['sourceId'])),
                $mx['orderNo'],
                $type,
                $mx['recordDate'],
                $settlementType,
                $period,
                $totalMoney,
                round($checkMoney, 2),
                round($totalMoney - $checkMoney, 2),
                text(array('name' => 'checkMoney[]','blur'=>"countMoney", 'value' => $array['money'])),
            ];
        }
        $total_tr = [
            9 => "<span id='checkMoneyTotal'>".$checkMoneyTotal."</span>",
        ];
        $list = $this->listTable(array('tr' => $sourceTr, 'end' => true, 'total' => $total_tr));
        $addOrderWord = L('inReceipt.edit.addOrder');
        $totalWord = L('inReceipt.edit.total');
        $but = <<<efo
                <span class="smallButton" onclick="layer('{$this->get('cla')}','addOrder',$('form[name=inReceiptEditForm]').serialize())">{$addOrderWord}</span>
efo;

        //表单
        $data['button'] = $this->tableShowButton($button);
        $body = $this->edit4([
            '基本信息' => [
                [
                    must . L('inReceipt.edit.client')."：" => clientProfileClass::kehuSelect(array( "value" => $info['targetId'])),
                    must . L('inReceipt.edit.recordDate')."：" => text(["name" => "recordDate", 'laydate' => [], "value" => $info['recordDate'] ?: $this->date]),
                    L('inReceipt.edit.manager')."：" => selectMultiple(["name" => "manager", "value" => $info['manager'] ?: self::$stid, 'where' => "state !='离职'", 'table' => "staff", 'sqlId' => 'stid', 'sqlField' => 'name', 'title' => L('inReceipt.edit.choice')]),
                ],
                [
                    L('inReceipt.edit.mxText')."：" => textarea(["name" => "text", "value" => $info['text']]),
                ],
            ]
        ]);
        $body .= $this->editList([
            'title' => L('inReceipt.edit.settlementType'),
            'html' => $this->listTable(array('tr' => $tr, 'end' => true )),
        ]);
        $body .= $this->editList([
            'id' => 'materialTable',
            'title' => L('inReceipt.edit.sourceOrder'),
            'button' => $but,
            'html' => $list,
        ]);
        $data['html'] = $this->pageEdit([
            "html" => $body,
            'hidden' => hidden(['name' => 'id', 'value' => $id]),
        ]);
        $data['html'] .= <<<efo
<script>
function addRow(e){
    let khid = $("[name='khid']").val();
    $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addRow',{khid:khid},function (res){
            $(e).closest('tr').after(res.data);
            resetNumber($(e).closest('tbody'))
         },'json');
}
function addOrder(){
     $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addOrderEdit',$("form[name='orderForm']").serialize(),function (res){
            $('#inReceiptAddOrder').hide();
            $("#materialTable tbody").append(res.html);
            countMoney()
            resetNumber($("#materialTable tbody"))
         },'json');
}
function countMoney(){
    let money = 0;
    $("#materialTable [name='checkMoney[]']").each(function() {
        money+=Number($(this).val());
    })
    $("#checkMoneyTotal").html(money.toFixed(2))
}
</script>

efo;
        //返回
        return $this->tab($data);
    }

    /**
     * Desc : 结算明细
     * User : you name
     * Date : 2024-02-20 14:51
     * @param array $data
     * @return array|false|string
     */
    public function listRow($data=[])
    {
        $list = isset($data['list'])?$data['list']:'';
        $mxId = isset($data['mxId'])&&$data['mxId']?$data['mxId']:self::getId();
        $field = ['acid', 'income', 'settleType', 'settleNo', 'mxText'];
        foreach ($field as $item){
            $array[$item] = isset($data[$item])?$data[$item]:$this->post($item);
        }
        $cloneArg = json_encode([
            'cla' => self::page,
            'fun' => 'listRow',
            'copy' => $field,
        ],320);
        $delArg = json_encode([
            'empty' => $field,
        ],320);
        $tr = [
            componentClass::tablePperation($list, "delRows(this,$delArg)","cloneRows(this,$cloneArg)", "addRow(this)"),
            hidden(array('name' => 'mxId[]', 'value' => $mxId)) .
            idSelect(array('name' => 'acid[]', 'title' => L('inReceipt.edit.choice'), 'sqlForm' => "account where coid = '" . self::$coid . "' and state = '启用'", 'sqlId' => 'id', 'sqlField' => 'name', 'value' => $array['acid'])),
            text(array('name' => 'income[]', 'value' => $array['income'])),
            select(array('name' => 'settleType[]', 'title' => L('inReceipt.edit.choice'), 'option' => explode('，', para('supplierSettlement')), 'value' => $array['settleType'])),
            text(array('name' => 'settleNo[]', 'value' => $array['settleNo'])),
            text(array('name' => 'mxText[]', 'class' => 'text textPrice', 'value' => $array['mxText'])),
        ];
        if($data){
            return $tr;
        }
        $json['html'] = $this->tableMany(['tr' => [$tr], 'thead' => false]);
        return json_encode($json, 320);
    }

    /**
     *添加一行
     */
    public function addRow()
    {
        $khid = $this->post('khid');//客户ID
        $kehu = query('kehu', "khid = '$khid'");
        $res = json_decode($this->listRow(),true);
        $json['data'] = $res['html'];
        return json_encode($json, 320);
    }

    public function editEdit()
    {
        $id = $this->post('id') ?: self::getId();
        //收款
        $mxIdArr = $this->post('mxId') ?: [];
        $acidArr = $this->post('acid');
        $incomeArr = $this->post('income') ?: [];
        $settleTypeArr = $this->post('settleType');
        $settleNoArr = $this->post('settleNo');
        $mxTextArr = $this->post('mxText');
        //源单
        $detailIdIdArr = $this->post('detailId') ?: [];
        $sourceIdArr = $this->post('sourceId');
        $checkMoneyArr = $this->post('checkMoney') ?: [];

        $field = [
            'targetId' => $this->post('khid'),
            'text' => $this->post('text'),
            'recordDate' => $this->post('recordDate'),
            'manager' => $this->post('manager'),
        ];
        $where = " id = '$id' ";
        $info = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = L('inReceipt.editEdit.power');
        } elseif (!empty($info['id']) && $info['state'] == '已确认') {
            $json['warn'] = L('inReceipt.editEdit.stateError');
        } else {
            $json['warn'] = '';
            //判断本次核销金额是否大于未核销金额
            foreach ($detailIdIdArr as $k => $mxId) {
                if (isset($sourceIdArr[$k]) && $sourceIdArr[$k]) {
                    //销售发货单
                    $targetInfo = query('sale_send_order', "id = '$sourceIdArr[$k]'");
                    //单据金额
                    $totalMoney = self::sale_money('sale_send_order', $targetInfo['id']);
                    $orderType = '销售发货单';
                    if (empty($targetInfo['id'])) {
                        $orderType = '销售退货单';
                        //销售退货单
                        $targetInfo = query('sale_refund_order', "id = '$sourceIdArr[$k]'");
                        //单据金额
                        $totalMoney = self::sale_money('sale_refund_order', $targetInfo['id']);
                    }
                    if ($targetInfo['khid'] != $field['targetId']) {
                        //转过的单子
                        $totalMoney = find(array('table' => 'write_off_order_replace', "where" => "sourceId = '$targetInfo[id]' and targetIn = '$field[targetId]'", 'sum' => "money"));
                    }
                    $totalMoney = $orderType == '销售退货单' ? -round($totalMoney, 2) : round($totalMoney, 2);
                    //已核销金额
                    $checkMoney = find(array('table' => "receipt_source as a join receipt as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$targetInfo[id]'", 'sum' => "money"));
                    $checkMoney += find(array('table' => "write_off_order_detail as a join write_off_order as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$targetInfo[id]'", 'sum' => "money"));
                    if ($checkMoneyArr[$k] > $totalMoney - $checkMoney) {
                        $json['warn'] = str_replace(['{{orderNo}}'], [$targetInfo['orderNo']], L('inReceipt.editEdit.overWriteOff'));
                        break;
                    }
                }
            }
            if (!static::is_null_array($detailIdIdArr)){
                //当前收款单总收款金额
                $totalInCom = round(array_sum($incomeArr),2);
                //总核销金额
                $totalCheckMoney = round(array_sum($checkMoneyArr),2);
                if ($totalCheckMoney > $totalInCom) {
                    $json['warn'] = L('inReceipt.editEdit.overCollection');
                }
            }

            if (empty($json['warn'])) {
                $this->startTrans();
                $isPass = true;//事务通过标志
                $kehu = query('kehu', "khid = '$field[targetId]'");
                if (!$info['id']) {
                    $userNo = codeTemplateClass::generateCode(self::page,[
                        'prefix' => 'SKD' . date('Ymd'),
                        'table' => self::table,
                        'field' => 'orderNo',
                        'where' => " and coid = '".self::$coid."'",
                    ],$field);
                    $field = array_merge($field, [
                        'id' => $id,
                        'orderNo' => $userNo,
                        'targetName' => $kehu['companyName'],
                        'state' => '草稿',
                        'target'=>'客户',
                        'classify' => 1,
                        'coid' => self::$coid,
                        'stid' => $this->control['stid'],
                        'time' => $this->time
                    ]);
                    $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
                    $orderNo = $userNo;
                } else {
                    $field['targetName'] = $kehu['companyName'];
                    $json['warn'] = static::update([
                        "table" => self::table,
                        "field" => $field,
                        "where" => $where
                    ]);
                    $orderNo = $info['orderNo'];
                }

                $index = 1;
                $endToBook=optionSettingClass::getSettingItem('往来账/出纳','endToBook');
                //结算信息
                foreach ($mxIdArr as $k => $nid) {
                    $mx = query(self::table . "_detail", "id = '$nid'");
                    if (!empty($mx['id'])) {
                        //更新
                        $warn = static::update([
                            "table" => self::table . "_detail",
                            "field" => [
                                'acid' => $acidArr[$k],
                                'money' => $incomeArr[$k],
                                'settleType' => $settleTypeArr[$k],
                                'settleNo' => $settleNoArr[$k],
                                'text' => $mxTextArr[$k],
                            ],
                            "where" => " id = '$nid'"
                        ]);
                    } else {
                        //新增
                        $warn = static::insert([
                            "table" => self::table . "_detail",
                            "field" => [
                                'id' => $nid,
                                'orderId' => $id,
                                'coid' => self::$coid,
                                'acid' => $acidArr[$k],
                                'money' => $incomeArr[$k],
                                'settleType' => $settleTypeArr[$k],
                                'settleNo' => $settleNoArr[$k],
                                'text' => $mxTextArr[$k],
                            ],
                        ]);
                    }
                    if (!in_array($warn, ['新增成功', '更新成功'])) {
                        $isPass = false;
                        $json['warn'] = $warn;
                        break;
                    }
                    //生成记账表
                    if ($endToBook){
                        $bookkeeping = query('bookkeeping', "sourceId = '$nid'");
                        $account = query('account', "id = '$acidArr[$k]'");
                        $kehu = query('kehu',"khid = '$field[targetId]'");
                        if (empty($bookkeeping['id'])) {
                            if($account['type'] == '现金'){
                                $userNo = codeTemplateClass::generateCode('cashBook',[
                                    'prefix' => date('Ymd',strtotime($field['recordDate'])),
                                    'table' => 'bookkeeping',
                                    'field' => 'orderNo',
                                    'where' => " and coid = '".self::$coid."'",
                                    'index'=>$index
                                ],[]);
                            }else{
                                $userNo = codeTemplateClass::generateCode('bankBook',[
                                    'prefix' => date('Ymd',strtotime($field['recordDate'])),
                                    'table' => 'bookkeeping',
                                    'field' => 'orderNo',
                                    'where' => " and coid = '".self::$coid."'",
                                    'index'=>$index
                                ],[]);
                            }
                            $warn = static::insert([
                                "table" => "bookkeeping",
                                "field" => [
                                    'id' => suiji(),
                                    'orderNo' => $userNo,
                                    'type' => $account['type'] == '现金' ?'现金': '银行账户',
                                    'coid' => self::$coid,
                                    'stid' => self::$stid,
                                    'accountId' => $account['id'],
                                    'classify' => '收-销售收入',
                                    'recordDate' => $field['recordDate'],
                                    'company' => $kehu['companyName'],
                                    'summary' => "收款单【{$orderNo}】",
                                    'income' => $incomeArr[$k],
                                    'settleType' => $settleTypeArr[$k],
                                    'billNo' => $settleNoArr[$k],
                                    'text' => $mxTextArr[$k],
                                    'sourceTable'=>self::table.'_detail',
                                    'sourceId'=>$nid,
                                    'state'=>optionSettingClass::getSettingItem('往来账/出纳','cashAndBankAudit')?'草稿':'已通过'
                                ],
                            ]);
                            $index++;
                        } else {
                            $warn = static::update([
                                "table" => "bookkeeping",
                                "field" => [
                                    'accountId' => $account['id'],
                                    'classify' => '收-销售收入',
                                    'recordDate' => $field['recordDate'],
                                    'company' => $kehu['companyName'],
                                    'summary' => "收款单【{$orderNo}】",
                                    'income' => $incomeArr[$k],
                                    'settleType' => $settleTypeArr[$k],
                                    'billNo' => $settleNoArr[$k],
                                    'text' => $mxTextArr[$k],
                                ],
                                'where'=>"id = '$bookkeeping[id]'"
                            ]);
                        }
                        if (!in_array($warn, ['新增成功', '更新成功'])) {
                            $isPass = false;
                            $json['warn'] = L('inReceipt.editEdit.fail');
                            break;
                        }
                    }

                }
                foreach ($detailIdIdArr as $k => $mxId) {
                    //销售发货单
                    $targetInfo = query('sale_send_order', "id = '$sourceIdArr[$k]'");
                    $table = 'sale_send_order';
                    if (empty($targetInfo['id'])) {
                        //销售退货单
                        $targetInfo = query('sale_refund_order', "id = '$sourceIdArr[$k]'");
                        $table = $targetInfo['id'] ? 'sale_refund_order' : '';
                    }
                    $mx = query(self::table . "_source", "id = '$mxId'");
                    if (!empty($mx['id'])) {
                        //更新
                        $warn = static::update([
                            "table" => self::table . "_source",
                            "field" => [
                                'sourceTable' => $table,
                                'sourceId' => $sourceIdArr[$k],
                                'money' => $checkMoneyArr[$k],
                            ],
                            "where" => " id = '$mxId'"
                        ]);
                    } else {
                        //新增
                        $warn = static::insert([
                            "table" => self::table . "_source",
                            "field" => [
                                'id' => $mxId,
                                'orderId' => $id,
                                'coid' => self::$coid,
                                'sourceTable' => $table,
                                'sourceId' => $sourceIdArr[$k],
                                'money' => $checkMoneyArr[$k],
                            ],
                        ]);
                    }
                    if (!in_array($warn, ['新增成功', '更新成功'])) {
                        $isPass = false;
                        $json['warn'] = $warn;
                        break;
                    }
                }

                if (in_array($json['warn'], ["新增成功", "更新成功"]) && $isPass) {
                    if ($json['warn'] == '新增成功') {
                        self::insertOperateLog($id,self::title,"新建");
                    }
                    $this->commitTrans();
                    if ($endToBook){
                        delete(array('table' => 'bookkeeping', 'where' => " sourceId in (select id from ".self::table . "_detail where id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id') and coid = '".self::$coid."'"));
                    }
                    delete(array('table' => self::table . "_detail", 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"));
                    delete(array('table' => self::table . "_source", 'where' => " id not in ('" . implode("','", $detailIdIdArr) . "') and orderId = '$id'"));
                    //添加日志
                    $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                    $text = str_replace(['{{staffName}}','{{type}}','{{id}}'], [$this->control['name'],$type,$id], L('inReceipt.editEdit.log'));
                    $this->logText(["type" => self::page, "text" => $text]);
                    //返回
                    $_SESSION['warn'] = $json['warn'];
                    $json['warn'] = 2;
                    $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
                } else {
                    $this->rollback();
                }
            }
        }

        resp:
        return json_encode($json, 320);
    }


    /**
     * 关联源单
     * @return bool|string
     */
    public function addOrder(): bool|string
    {
        $html =
            select(array("name" => "orderType", "title" => L('inReceipt.addOrder.orderType'), 'option' => ['销售发货单', '销售退货单'])) .
            text(array("name" => "orderNo", "title" => L('inReceipt.addOrder.orderNo'))) .
            text(array("name" => "recordDate", 'class' => 'width200', 'laydate' => ['type' => 'date', 'range' => '~'], "title" => L('inReceipt.addOrder.recordDate'))) .
            hidden(array('name' => 'id', 'value' => $this->post('id'))) .
            hidden(array('name' => 'khid', 'value' => $this->post('khid'))) .
            hidden(array('name' => 'sourceId', 'value' => $this->post('sourceId') ? implode(',', $this->post('sourceId')) : ''));
        $button = "<input style='margin-left: 5px' onclick=\"addOrder()\" type='button' class='searchSub' value='".L('inReceipt.addOrder.sub')."'>";
        $html = $this->search($html);
        return $this->layer(array("title" => L('inReceipt.addOrder.add'), "height" => 600, "width" => 1000, "html" => $html, "button" => $button));
    }

    /**
     * 关联源单
     * @return bool|string
     */
    public function addOrderSearch(): bool|string
    {
        $khid = $this->post('khid');
        $sourceId = $this->post('sourceId') ? explode(',', $this->post('sourceId')) : [];
        $where = " coid='" . self::$coid . "' and (khid = '$khid' or id in (select distinct sourceId from write_off_order_replace where targetIn = '$khid' and coid = '" . self::$coid . "' and type = '应收转应收')) and id not in ('" . implode("','", $sourceId) . "')";
        $and = '';
        $like = [
            'orderNo' => $this->post('orderNo'),
        ];
        $equal = [
            'state' => '已确认',
        ];
        if ($this->post('recordDate')) {
            //单据日期
            $and .= self::timeComparison($this->post('recordDate'), 'date', 'recordDate');
        }
        $where .= search(["like" => $like, "=" => $equal]) . $and;
        $whereOne = $whereTwo = '';
        if ($this->post('orderType') == '销售发货单') {
            $whereTwo = " and 1!=1";
        } elseif ($this->post('orderType') == '销售退货单') {
            $whereOne = " and 1!=1";
        }
//        $whereOne .= " and ((select ifnull(sum(i.money),0) from sale_send_order_detail as detail join inventory_detail as i on detail.id =i.sourceId where detail.orderId = sale_send_order.id)+(select ifnull(sum(money),0) from write_off_order_replace where sourceId = sale_send_order.id and targetIn = '$khid') != (select ifnull(sum(abs(a.money)),0) from receipt_source as a join receipt as b on a.orderId = b.id where b.state = '已确认' and a.sourceId =sale_send_order.id)+(select ifnull(sum(abs(a.money)),0) from write_off_order_detail as a join write_off_order as b on a.orderId = b.id where b.state = '已确认' and a.sourceId = sale_send_order.id))";

        $whereTwo .= " and ((select ifnull(sum(i.money),0) from sale_refund_order_detail as detail join inventory_detail as i on detail.id =i.sourceId where detail.orderId = sale_refund_order.id)+(select ifnull(sum(money),0) from write_off_order_replace where sourceId = sale_refund_order.id and targetIn = '$khid')) != ((select ifnull(sum(abs(a.money)),0) from receipt_source as a join receipt as b on a.orderId = b.id where b.state = '已确认' and a.sourceId =sale_refund_order.id)+(select ifnull(sum(abs(a.money)),0) from write_off_order_detail as a join write_off_order as b on a.orderId = b.id where b.state = '已确认' and a.sourceId = sale_refund_order.id))";

        $page = $this->page([
            "table" => "sale_send_order where  {$where} {$whereOne} UNION select id,time from sale_refund_order",
            'field' => 'id,time',
            "where" => $where . $whereTwo,
            'pageNum' => 50,
            'union' => "select ifnull(count(id),0) as num from sale_send_order where {$where} {$whereOne} UNION select ifnull(count(id),0) as num from sale_refund_order where {$where} {$whereTwo}",
            "order" => "`time` desc",
        ]);
        $json['sql'] = $page['sql'];
        //获取表头
        $checkAll = $this->checkAll("orderForm", "orderId");
        $tr[] = [$checkAll, L('inReceipt.addOrderSearch.orderNo'), L('inReceipt.addOrderSearch.type'), L('inReceipt.addOrderSearch.recordDate'),L('inReceipt.addOrderSearch.settlementType'),L('inReceipt.addOrderSearch.period'), L('inReceipt.addOrderSearch.totalMoney'), L('inReceipt.addOrderSearch.checkMoney')];
        //获取记录
        foreach ($page['array'] as $array) {
            $dominate = array(
                "box" => array("name" => "orderId", "value" => $array['id']),
            );
            $settlementType = '';
            $period = '';
            $info = query('sale_send_order', "id = '$array[id]'");
            $type = '销售发货单';
            //单据金额
            $totalMoney = self::sale_money('sale_send_order', $array['id']);
            if (empty($info['id'])) {
                $info = query('sale_refund_order', "id = '$array[id]'");
                $type = '销售退货单';
                //单据金额
                $totalMoney = self::sale_money('sale_refund_order', $array['id']);
            }else{
                $settlementType = $info['settlementType'];
                $period = $this->settlementPeriod($info['settlementType'],$info['recordDate'],$info['settlementDay']);
            }
            if ($info['khid'] != $khid) {
                //转过的单子
                $totalMoney = find(array('table' => 'write_off_order_replace', "where" => "sourceId = '$info[id]' and targetIn = '$khid'", 'sum' => "money"));
            }
            $checkMoney = find(array('table' => "receipt_source as a join receipt as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$info[id]'", 'sum' => "money"));
            //核销单
            $checkMoney += find(array('table' => "write_off_order_detail as a join write_off_order as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$info[id]'", 'sum' => "money"));
            $tr[] = array(
                $this->dominate($dominate),
                $info['orderNo'],
                $type,
                $settlementType,
                $period,
                $info['recordDate'],
                round($totalMoney, 2),
                round($checkMoney, 2)
            );
        }
        $json['html'] = $page['hint'] .
            "<form name='orderForm'>" .
            hidden(array('name' => 'id', 'value' => $this->post('id'))) .
            hidden(array('name' => 'khid', 'value' => $khid)) .
            $this->tableMany(array("tr" => $tr, "showSort" => true, "page" => $page['para'])) .
            "</form>" .
            $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 关联源单
     */
    public function addOrderEdit(): bool|string
    {
        $khid = $this->post('khid');
        $mxIdArr = $this->post('orderId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = L('inReceipt.addOrderEdit.power');
        } elseif (empty($mxIdArr) || !is_array($mxIdArr)) {
            $json['warn'] = L('inReceipt.addOrderEdit.sourceOrder');
        } elseif (empty($khid)) {
            $json['warn'] = L('inReceipt.addOrderEdit.clientEmpty');
        } else {
            $tr = [];
            foreach ($mxIdArr as $id) {
                $info = query('sale_send_order', "id = '$id'");
                //单据金额
                $totalMoney = self::sale_money('sale_send_order', $info['id']);
                $type = '销售发货单';
                $settlementType = '';
                $period = '';
                //核销单(待定)
                if (empty($info['id'])) {
                    $info = query('sale_refund_order', "id = '$id'");
                    //单据金额
                    $totalMoney = self::sale_money('sale_refund_order', $info['id']);
                    $type = '销售退货单';
                }else{
                    $settlementType = $info['settlementType'];
                    $period = $this->settlementPeriod($info['settlementType'],$info['recordDate'],$info['settlementDay']);
                }
                if ($info['khid'] != $khid) {
                    //转过的单子
                    $totalMoney = find(array('table' => 'write_off_order_replace', "where" => "sourceId = '$info[id]' and targetIn = '$khid'", 'sum' => "money"));
                }
                //已核销金额
                $checkMoney = find(array('table' => "receipt_source as a join receipt as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$info[id]'", 'sum' => "money"));
                //核销单
                $checkMoney += find(array('table' => "write_off_order_detail as a join write_off_order as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$info[id]'", 'sum' => "money"));
                $totalMoney = $type == '销售退货单' ? -round($totalMoney, 2) : round($totalMoney, 2);
                $checkMoney = round($checkMoney, 2);
                $unCheckMoney = $totalMoney - $checkMoney;
                $uid = self::getId();
                $tr[]              = [
                    componentClass::tablePperation('',"delTableRow(this)").
                    hidden(array('name' => 'detailId[]', 'value' => $uid)) .
                    hidden(array('name' => 'sourceId[]', 'value' => $id)),
                    $info['orderNo'],
                    $type,
                    $info['recordDate'],
                    $settlementType,
                    $period,
                    $totalMoney,
                    $checkMoney,
                    $unCheckMoney,
                    text(array('name' => 'checkMoney[]', 'blur' => 'countMoney', 'other' => self::digitalFiltering('amount'), 'value' => $unCheckMoney)),
                ];
            }
            $json['html'] = $this->tableMany(array('tr' => $tr, 'thead' => false));
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }


    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = L('inReceipt.detail.power');
        } else {
            //菜单
            $data = array(
                "id" => $info['id'],
            );

            $button = [];
            if ($this->power(self::page, "confirm") && $info['state'] == '待确认') {
                $button[] = [
                    "name" => '复核',
                    "type" => "弹出层",
                    "cla" => $this->get('cla'),
                    "fun" => "operate",
                    "post" => ["act" => 'confirm', "id" => $info['id']],
                    'style' => 'li-btn-blue-bg',
                ];
            }
            if ($info['state'] == '草稿') {
                if ($this->power(self::page, "edit")) {
                    //按钮
                    $button[] = [
                        "name" => L('inReceipt.detail.sub'),
                        "type" => "弹出层",
                        "cla" => $this->get('cla'),
                        "fun" => "operate",
                        "post" => ["act" => 'commit', "id" => $info['id']],
                        'style' => 'li-btn-blue-bg',
                    ];
                    //按钮
                    $button[] = [
                        "name" => L('inReceipt.detail.edit'),
                        "type" => "顶部页卡",
                        "title" => L('inReceipt.detail.editDetail'),
                        "url" => $this->root . "control/adIndex.html?cla={$this->get('cla')}&fun=edit&id=" . $info['id'],

                    ];
                }
                if ($this->power(self::page, "del")) {
                    //按钮
                    $button[] = [
                        "name" => L('inReceipt.detail.del'),
                        "type" => "弹出层",
                        "cla" => $this->get('cla'),
                        "fun" => "operate",
                        "post" => ["act" => 'del', "id" => $info['id']],
                    ];
                }
            }
            if ($this->power(self::page, "cancel") && $info['state'] != '草稿') {
                $button[] = [
                    "name" => "撤回",
                    "type" => "弹出层",
                    "cla"  => $this->get('cla'),
                    "fun"  => "operate",
                    "post" => ["act" => 'cancel', "id" => $info['id']],
                ];
            }
            if ($this->power(self::page, "print")) {
                //按钮
                $button[] = [
                    "name" => "打印",
                    "type" => "点击事件",
                    "fun" => "window.open('" . root . "control/adIndex.html?cla=" . self::page . "&fun=printPage&id={$info['id']}')",
                ];
            }
            //操作记录
            $button[] = self::operateLogBut($info['id'],1);

            $tr[] = [L('inReceipt.detail.account'), L('inReceipt.detail.money').'(' . static::$unit . ')', L('inReceipt.detail.settleType'), L('inReceipt.detail.settleNo'), L('inReceipt.detail.text')];
            $result = find(array('table' => self::table . "_detail", 'where' => "orderId = '$info[id]' order by list"));
            foreach ($result['array'] as $array) {
                $account = query('account', "id = '$array[acid]'");
                $tr[] = [
                    $account['name'],
                    $array['money'],
                    $array['settleType'],
                    $array['settleNo'],
                    $array['text'],
                ];
            }
            $income = find(array('table' => self::table . "_detail", 'sum' => "money", 'where' => "orderId = '$info[id]'"));

            $total_tr = [
                1=>$income
            ];
            $sourceTr[] = [L('inReceipt.addOrderSearch.orderNo'), L('inReceipt.addOrderSearch.type'), L('inReceipt.addOrderSearch.recordDate'), L('inReceipt.addOrderSearch.settlementType'),L('inReceipt.addOrderSearch.period'),L('inReceipt.addOrderSearch.totalMoney').'(' . static::$unit . ')', L('inReceipt.addOrderSearch.checkMoney').'(' . static::$unit . ')', L('inReceipt.addOrderSearch.notWrittenOff').'(' . static::$unit . ')', L('inReceipt.addOrderSearch.thisMoney').'(' . static::$unit . ')'];
            $result = find(array('table' => self::table . "_source", 'where' => "orderId = '$info[id]' order by list"));
            $receiptMoney = $allOffMoney = $offMoney = 0;
            foreach ($result['array'] as $array) {
                $settlementType = '';
                $period = '';
                if ($array['sourceTable'] == 'sale_send_order') {
                    //销售发货单
                    $targetInfo = query('sale_send_order', "id = '$array[sourceId]'");
                    $type = '销售发货单';
                    $settlementType = $targetInfo['settlementType'];
                    $period = $this->settlementPeriod($targetInfo['settlementType'],$targetInfo['recordDate'],$targetInfo['settlementDay']);
                    //单据金额
                    $totalMoney = self::sale_money('sale_send_order', $array['sourceId']);
                } else {
                    $type = '销售退货单';
                    //销售退货单
                    $targetInfo = query('sale_refund_order', "id = '$array[sourceId]'");
                    //单据金额
                    $totalMoney = self::sale_money('sale_refund_order', $array['sourceId']);
                }
                if ($targetInfo['khid'] != $info['targetId']) {
                    //转过的单子
                    $totalMoney = find(array('table' => 'write_off_order_replace', "where" => "sourceId = '$targetInfo[id]' and targetIn = '$info[targetId]'", 'sum' => "money"));
                }
                $totalMoney = $type == '销售退货单' ? -self::formattingFigure($totalMoney) : self::formattingFigure($totalMoney);
                $receiptMoney += $totalMoney;
                $checkMoney = find(array('table' => "receipt_source as a join receipt as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$targetInfo[id]'", 'sum' => "money"));
                $checkMoney += find(array('table' => "write_off_order_detail as a join write_off_order as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$targetInfo[id]'", 'sum' => "money"));
                $allOffMoney += $checkMoney;
                $offMoney += $array['money'];
                $sourceTr[] = [
                    $targetInfo['orderNo'],
                    $type,
                    $targetInfo['recordDate'],
                    $settlementType,
                    $period,
                    $totalMoney,
                    self::formattingFigure($checkMoney),
                    self::formattingFigure($totalMoney - $checkMoney),
                    $array['money'],
                ];
            }
            //未核销金额
            $unOffMoney = $receiptMoney - $allOffMoney;
            $total_source_tr = [
                5=>self::formattingFigure($receiptMoney),
                6=>self::formattingFigure($allOffMoney),
                7=>self::formattingFigure($unOffMoney),
                8=>self::formattingFigure($offMoney)
            ];
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow(array(
                "基本信息" => array(
                    array(
                        L('inReceipt.detail.targetName') => $info['targetName'],
                        L('inReceipt.detail.recordDate') => $info['recordDate'],
                        L('inReceipt.detail.manager') => self::findStaff($info['manager']),
                        L('inReceipt.detail.orderNo') => $info['orderNo'],
                    ),
                    array(
                        L('inReceipt.detail.stid') => self::findStaff($info['stid']),
                        L('inReceipt.detail.state') => $info['state']
                    ),
                    array(
                        L('inReceipt.detail.text') => pre($info['text']),
                    ),
                )
            ));
            $data['html'] .= $this->detailList([
                'title' => L('inReceipt.detail.billingInfo'),
                'html' => $this->listTable(array('tr' => $tr, 'showEmpty' => true, 'total' => $total_tr, 'showSort' => true)),
            ]);
            $data['html'] .= $this->detailList([
                'title' => L('inReceipt.detail.sourceOrder'),
                'html' => $this->listTable(array('tr' => $sourceTr, 'showEmpty' => true, 'total' => $total_source_tr, 'showSort' => true)),
            ]);
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    /**
     * 判断本次核销金额是否大于未核销金额
     */
    public function judgeOffMoney($info): array|string
    {
        $all = find(array('table' => self::table . "_source", 'where' => "orderId = '$info[id]' order by list"));
        $writeOffArray = [];
        foreach ($all['array'] as $array) {
            if ($array['sourceTable'] == 'sale_send_order') {
                //销售发货单
                $orderType = '销售发货单';
                $targetInfo = query('sale_send_order', "id = '$array[sourceId]'");
            } else {
                //销售退货单
                $orderType = '销售退货单';
                $targetInfo = query('sale_refund_order', "id = '$array[sourceId]'");
            }
            //单据金额
            $totalMoney = self::sale_money($array['sourceTable'], $array['sourceId']);
            if ($targetInfo['khid'] != $info['targetId']) {
                //转过的单子
                $totalMoney = find(array('table' => 'write_off_order_replace', "where" => "sourceId = '$targetInfo[id]' and targetIn = '$info[targetId]'", 'sum' => "money"));
            }
            $totalMoney = $orderType == '销售退货单' ? -round($totalMoney, 2) : round($totalMoney, 2);

            //已核销金额
            $checkMoney = find(array('table' => "receipt_source as a join receipt as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$targetInfo[id]'", 'sum' => "money"));
            $checkMoney += find(array('table' => "write_off_order_detail as a join write_off_order as b on a.orderId = b.id", "single" => "b.state = '已确认' and a.sourceId = '$targetInfo[id]'", 'sum' => "money"));
            if ($array['money'] > round($totalMoney - $checkMoney,2)) {
                return str_replace(['{{orderNo}}'], [$targetInfo['orderNo']], L('inReceipt.judgeOffMoney.tips'));
            }elseif($array['money'] == round($totalMoney - $checkMoney,2)){
                $writeOffArray[] = ['sourceTable'=>$array['sourceTable'],'sourceId'=>$array['sourceId'],'isWriteOff'=>1];
            }
        }
        return $writeOffArray;
    }

    /**
     * 确认
     */
    public function confirmEdit(): bool|string
    {
        $id = $this->post('id');
        $info = query(self::table, " id = '$id'");
        $field = [
            'state' => '已确认',
            'checkId' => self::$stid,
            'confirmTime' => $this->time
        ];
        $res = $this->judgeOffMoney($info);
        if (!$this->power(self::page, 'confirm')) {
            $json['warn'] = L('inReceipt.confirmEdit.power');
        } elseif (empty($info['id'])) {
            $json['warn'] = L('inReceipt.confirmEdit.empty');
        } elseif (!is_array($res)) {
            $json['warn'] = $res;
        } elseif ($info['state'] != '待确认') {
            $json['warn'] = L('inReceipt.confirmEdit.stateError');
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            $all = find(array('table' => self::table . '_detail', 'where' => "orderId = '$info[id]' order by list"));
            foreach ($all['array'] as $array) {
                $bool = accountClass::record_ac($array['acid'], '收入', $array['money'], str_replace(['{{orderNo}}'], [$info['orderNo']], L('inReceipt.confirmEdit.income')), targetName: $info['targetName'], targetDate: $info['recordDate'], orderNo: $info['orderNo'], hiddenText: "收款单【{$info['orderNo']}】收入，明细ID：{$array['id']}");
                if ($bool !== true) {
                    $json['warn'] = $bool;
                    break;
                }
            }
            $all = find(array('table' => self::table . '_source', 'where' => "orderId = '$info[id]' order by list"));
            foreach ($all['array'] as $array) {
                $bool = supplierClass::record_cl($info['targetId'], '-', -$array['money'], $info['recordDate'], self::table . '_source', $array['id'], str_replace(['{{orderNo}}'], [$info['orderNo']], L('inReceipt.confirmEdit.writeOff')), orderNo: $info['orderNo'], hiddenText: "明细ID：{$array['id']}", classify: '收款单核销');
                if ($bool !== true) {
                    $json['warn'] = $bool;
                    break;
                }
            }
            //收款单总收入金额
            $income = find(['table'=>self::table.'_detail','where'=>"orderId = '$info[id]'",'sum'=>"money"]);
            //收款单核销金额
            $checkMoney = find(['table'=>self::table.'_source','where'=>"orderId = '$info[id]'",'sum'=>"money"]);
            //收款单剩余金额
            $remindMoney = round($income-$checkMoney,2);
            if ($remindMoney !=0){
                $bool = supplierClass::record_cl($info['targetId'], '-', -$remindMoney, $info['recordDate'], self::table, $info['id'], "收款单【{$info['orderNo']}】收款", orderNo: $info['orderNo'], hiddenText: "收款单中未核销的部分", classify: '收款单');
                if ($bool !== true) {
                    $json['warn'] = $bool;
                }
            }

            if (in_array($json['warn'], ["更新成功"])) {
                // 单据是否需要复核
                if(!in_array(self::page,self::$publicSettings['documentReview'])) {
                    self::insertOperateLog($info['id'],self::title,"提交、复核");
                }else{
                    self::insertOperateLog($info['id'],self::title,"复核");
                }
                $this->commitTrans();
                //修改源单核销状态
                foreach ($res as $val){
                    update(array(
                        "table" => $val['sourceTable'],
                        "field" => ['isWriteOff'=>$val['isWriteOff']],
                        "where" => "id = '$val[sourceId]'",
                    ));
                }
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = str_replace(['{{staffName}}','{{type}}','{{id}}'], [$this->control['name'],$type,$id], L('inReceipt.confirmEdit.log'));
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 撤回
     */
    public function cancelEdit()
    {
        $id    = $this->post('id');
        $info = query(self::table, " id = '$id'");
        $field = [
            'state'       => '草稿',
            'checkId'     => '',
            'confirmTime' => '',
        ];
        if (!$this->power(self::page, 'cancel')) {
            $json['warn'] = '你还没有撤回权限';
        } elseif (empty($info['id'])) {
            $json['warn'] = '未找到此收款单';
        } elseif ($info['state'] == '草稿') {
            $json['warn'] = '此收款单草稿状态下，无需撤回';
        } elseif (static::total(array('table' => 'voucher', "where" => "id = '$info[voucherId]'")) > 0) {
            $json['warn'] = '此收款单存在业务凭证，不能撤回';
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));

            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();

                $all = find(array('table' => self::table . '_detail', 'where' => "orderId = '$info[id]' order by list"));
                foreach ($all['array'] as $array) {
                    delete(array('table' => 'account_record', 'where' => "acid = '$array[acid]' and orderNo = '$info[orderNo]'"));
                }
                delete(array('table' => 'record', 'where' => "sourceId = '$info[id]'"));

                self::insertOperateLog($id, self::title, "撤回");
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * Desc : 提交前数据验证
     * User : you name
     * Date : 2023-11-17 16:04
     * @param $info
     * @return string|bool
     */
    public function dataValidation($info): string|bool
    {
        $annotation = [
            'targetId' => L('inReceipt.edit.client'),
            'recordDate' => L('inReceipt.edit.recordDate'),
        ];
        $rules = [
            'targetId' => 'required',
            'recordDate' => 'required',
        ];
        // 校验是否符合规则
        $vt = new \verify();
        $result = $vt->setAliases($annotation)->validate($info, $rules)->isOk();
        if ($result === false) {
            return $vt->getErrs()[0];  // 多个规则提示最前面一条
        }
        $result = find(array('table' => self::table . "_detail", 'field' => 'id,money,acid,settleType', 'where' => "orderId = '$info[id]' order by list"));
        if(count($result['array']) == 0){
            return "请完善结算信息";
        }
        if(static::is_null_array(array_column($result['array'],'acid'))){
            return "结算信息【收款账户】不能为空";
        }
        if(static::is_null_array(array_column($result['array'],'settleType'))){
            return "结算信息【结算方式】不能为空";
        }
        if(static::is_null_array(array_column($result['array'],'money'),false)){
            return "结算信息【收款金额】不能为空，且必须大于0";
        }

        return true;
    }
    /**
     * 提交
     */
    public function commitEdit(): bool|string
    {
        $id = $this->post('id');
        $info = query(self::table, " id = '$id'");
        $field = [
            'state' => '待确认',
        ];
        //提交前数据验证
        $json['warn'] = $this->dataValidation($info);
        if($json['warn'] !== true){
            goto resp;
        }
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = L('inReceipt.commitEdit.power');
        } elseif (empty($info['id'])) {
            $json['warn'] = L('inReceipt.commitEdit.empty');
        } elseif ($info['state'] != '草稿') {
            $json['warn'] = L('inReceipt.commitEdit.stateError');
        } else {
            $this->startTrans();
            $json['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                // 单据是否需要复核
                if(!in_array(self::page,self::$publicSettings['documentReview'])){
                    $resultJson = $this->confirmEdit();
                    $json = json_decode($resultJson,true);
                    if ($json['warn'] != 2){
                        $this->rollback();
                        goto resp;
                    }
                }else {
                    self::insertOperateLog($info['id'],self::title,"提交");
                }
                $this->commitTrans();
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = str_replace(['{{staffName}}','{{type}}','{{id}}'], [$this->control['name'],$type,$id], L('inReceipt.commitEdit.log'));
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
                $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $info['id'];
            } else {
                $this->rollback();
            }
        }
        resp:
        return json_encode($json, 320);
    }

    // 操作中转
    public function operate()
    {
        $act = $this->post('act') ?? '';
        $pwd = $word = false; // 需要密码
        $form = $power = '';
        switch ($act) {
            case 'confirm':
                $act = 'confirm';
                $msg = L('inReceipt.operate.sure');
                $title = L('inReceipt.operate.sureTitle');
                $function = 'confirmEdit';
                $form = self::page . 'OperateForm, detailForm';
                $power = '';
                $word = true;
                break;
            case 'commit':
                $act = 'edit';
                $msg = L('inReceipt.operate.edit');
                $title = L('inReceipt.operate.editTitle');
                $function = 'commitEdit';
                $form = self::page . 'OperateForm, detailForm';
                $power = '';
                $word = true;
                break;
            case 'cancel':
                $act      = 'cancel';
                $msg      = '撤回';
                $title    = '是否确认撤回此收款单？';
                $function = 'cancelEdit';
                $form     = self::page . 'OperateForm, detailForm';
                $power    = '';
                $word     = true;
                break;
            default:
                $act = 'del';
                $msg = L('inReceipt.operate.del');
                $title = self::page . 'Delete';
                $function = 'delete';
                $form = self::page . 'OperateForm, listForm, quoForm';
                $power = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = str_replace(['{{msg}}'], [$msg], L('inReceipt.operate.warn'));
            $json = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title' => $title,
                'function' => $function,
                'form' => $form,
                'power' => $power,
                'pwd' => $pwd,
                'word' => $word
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 删除
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = L('inReceipt.delete.power');
        } elseif (empty($array)) {
            $json['warn'] = L('inReceipt.delete.noChoice');
        } else {
            $text = "";
            $x = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] == '已确认') {
                    $warn = L('inReceipt.delete.fail');
                } else {
                    //最后删除基本参数
                    delete(array("table" => self::table, "where" => " id = '$id' "));
                    delete(array("table" => self::table . "_detail", "where" => " orderId = '$id' "));
                    delete(array("table" => self::table . "_source", "where" => " orderId = '$id' "));
                    delete(array("table" => "auditing_follow", "where" => " typeId = '$id' "));
                    //返回
                    $warn = L('inReceipt.delete.success');
                    $x++;
                }
                $text .= str_replace(['{{id}}'], [$info['id']], L('inReceipt.delete.text')) . $warn . "。<br>";
            }
            //添加日志
            $text = str_replace(['{{staffName}}'], [$this->control['name']], L('inReceipt.delete.log')) . "<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = str_replace(['{{x}}'], [$x], L('inReceipt.delete.warn'));
            $json['warn'] = 2;
            $json['href'] = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }


    /**
     * 批量打印
     *
     * @return string
     */
    public function batchPrint(): string
    {
        $lists = $this->get('lists');
        if (empty($lists)) {
            exit('参数错误');
        } else {
            $listId = base64_decode($lists, true);
            $array = explode(',', $listId);
            $data = [];
            foreach ($array as $id) {
                $data[] = static::printPage($id, false);
            }
            return (new printTemplateClass())->start(self::page, $data);
        }
    }

    /**
     * 打印
     *
     * @return string
     */
    public function printPage($param = '', $isReturn = true): string|array
    {
        $id = $param ?: $this->get('id');
        $info = query(self::table, " id = '$id'");
        $info['companyName'] = query('company', "coid = '" . self::$coid . "'")['name']; //公司名称//公司名称
        $info['title'] = self::title;
        $info['printTime'] = $this->time;
        $info['stid'] = self::findStaff($info['stid']);
        $info['khName'] = query('kehu', "khid = '$info[targetId]'")['companyName'];
        $info['qr'] = "source=" . self::table . "&id=" . $info['id'];
        $info['salemans'] =  self::findStaff($info['manager']);
        $detail = find(['table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"])['array'];
        $items = [];
        $x = 1;
        $totalMoney = 0;
        foreach ($detail as $array) {
            $account = query('account', "id = '$array[acid]'");
            $items[] = [
                'no' => $x,
                'accountName' => $account['name'],
                'money' => self::lostZero($array['money'], 'pricePrecision'),
                'settleType' => $array['settleType'],
                'settleNo' => $array['settleNo'],
                'text' => $array['text'],
            ];
            $x++;
            $totalMoney += $array['money'];
        }
        $append = [
            'no' => '合计',
            'money' => self::lostZero($totalMoney, 'amount'),
        ];
        $items[] = $append;
        $info['detail'] = $items;
        if ($isReturn) {
            return (new printTemplateClass())->start(self::page, $info);
        } else {
            return $info;
        }
    }
}

